package com.ourteam.product.requirement.service;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import com.ourteam.product.requirement.dao.IProductFeatureCheckListDAO;
import com.ourteam.product.requirement.dao.IProductFeatureDAO;
import com.ourteam.product.requirement.dao.IProductGlossaryDAO;
import com.ourteam.product.requirement.dao.IProductRequirementDAO;
import com.ourteam.product.requirement.dao.ProductCodeGen;
import com.ourteam.product.requirement.dao.ProductCodeGenDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductCodeTemplate;
import com.ourteam.product.requirement.dao.ProductCodeTemplateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductDefine;
import com.ourteam.product.requirement.dao.ProductFeature;
import com.ourteam.product.requirement.dao.ProductFeatureCheckList;
import com.ourteam.product.requirement.dao.ProductFeatureCheckListDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductFeatureDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossary;
import com.ourteam.product.requirement.dao.ProductGlossaryAttr;
import com.ourteam.product.requirement.dao.ProductGlossaryAttrDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossaryChangLog;
import com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductGlossaryRelate;
import com.ourteam.product.requirement.dao.ProductGlossaryRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirement;
import com.ourteam.product.requirement.dao.ProductRequirementDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirementFeatureRelate;
import com.ourteam.product.requirement.dao.ProductRequirementFeatureRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirementRelate;
import com.ourteam.product.requirement.dao.ProductRequirementRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRoleDefine;
import com.ourteam.product.requirement.dao.ProductRoleDefineDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRoleRelate;
import com.ourteam.product.requirement.dao.ProductRoleRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductTeam;
import com.ourteam.product.requirement.dao.ProductTeamDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductVersion;
import com.ourteam.product.requirement.dao.ProductVersionRelate;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOFactory;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOQueryBean;
import com.ourteam.product.requirement.domain.ProductDefineBean;
import com.ourteam.product.requirement.domain.ProductElementTypeEnum;
import com.ourteam.product.requirement.domain.ProductFeatureBean;
import com.ourteam.product.requirement.domain.ProductFeatureCheckListBean;
import com.ourteam.product.requirement.domain.ProductGlossaryAttrBean;
import com.ourteam.product.requirement.domain.ProductGlossaryBean;
import com.ourteam.product.requirement.domain.ProductGlossaryRelateBean;
import com.ourteam.product.requirement.domain.ProductRequirementBean;
import com.ourteam.product.requirement.domain.ProductRequirementFeatureRelateBean;
import com.ourteam.product.requirement.domain.ProductRequirementRelateBean;
import com.ourteam.product.requirement.domain.ProductRoleDefineBean;
import com.ourteam.product.requirement.domain.ProductRoleRelateBean;
import com.ourteam.product.requirement.domain.ProductTeamBean;
import com.ourteam.product.requirement.domain.ProductVersionRelateBean;
import com.ourteam.system.domain.SystemUser;

/**
 *
 * Template Name : 业务服务实现 Template Version : 1 Template Last Modfiy Date : Mon
 * Nov 06 10:49:11 IRKT 2017 Auto Generate Date : 2017-11-23 10:38:03
 *
 */
public class ProductServiceImpl extends AbstractProductService {
	/**
	 * 查询产品
	 * 
	 * @param aProductDefineDAOQueryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductDefineBean[] doQueryProductDefines(
			final com.ourteam.product.requirement.dao.ProductDefineDAOQueryBean aProductDefineDAOQueryBean)
			throws Exception {
		ProductDefine[] productDefines = productDefineDao.query(aProductDefineDAOQueryBean);

		return ProductDefineBean.toArray(productDefines);
	}

	/**
	 * 查询产品�?
	 * 
	 * @param aProductDefineDAOQueryBean
	 * @throws Exception
	 */
	protected int doQueryProductDefineCount(
			final com.ourteam.product.requirement.dao.ProductDefineDAOQueryBean aProductDefineDAOQueryBean)
			throws Exception {
		return productDefineDao.queryCount(aProductDefineDAOQueryBean);
	}

	/**
	 * 新建产品定义
	 * 
	 * @param aProductDefine
	 * @throws Exception
	 */
	protected void doCreateProductDefine(final com.ourteam.product.requirement.domain.ProductDefineBean aProductDefine)
			throws Exception {
		ProductDefine productDefine = aProductDefine.convertToProductDefine();

		if (productDefineDao.checkIsUnique(productDefine) == false) {
			throw new Exception("product define '" + productDefine.getProductName() + "' already exist ");
		}

		if (productDefine.getSubmitterId() != 0) {
			SystemUser systemUser = this.sysUserService.getSysUserById(productDefine.getSubmitterId());
			if (systemUser != null) {
				productDefine.setCreateTime(new Date());
				productDefine.setCreatorName(systemUser.getName());
			}
		}

		productDefineDao.insert(productDefine);

		String productCode = getProductElementCode(productDefine.getId(), ProductElementTypeEnum.PRODUCT_DEFINE);

		productDefine.setProductCode(productCode);

		productDefineDao.update(productDefine);
	}

	/**
	 * 更新产品定义
	 * 
	 * @param aProductDefine
	 * @throws Exception
	 */
	protected void doModifyProductDefine(final com.ourteam.product.requirement.domain.ProductDefineBean aProductDefine)
			throws Exception {
		ProductDefine productDefine = aProductDefine.convertToProductDefine();

		if (productDefineDao.checkIsUnique(productDefine) == false) {
			throw new Exception("product define '" + productDefine.getProductName() + "' already exist ");
		}

		if (productDefine.getSubmitterId() != 0) {
			SystemUser systemUser = this.sysUserService.getSysUserById(productDefine.getSubmitterId());
			if (systemUser != null) {
				productDefine.setLastModifyTime(new Date());
				productDefine.setLastModifierName(systemUser.getName());
			}
		}

		productDefineDao.update(productDefine);
	}

	/**
	 * 删除产品定义
	 * 
	 * @param aProductDefineId
	 * @throws Exception
	 */
	protected void doDeleteProductDefine(final long aProductDefineId) throws Exception {
		productDefineDao.delete(aProductDefineId);
	}

	/**
	 * 根据ID取得产品定义
	 * 
	 * @param productDefineId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductDefineBean doGetProductDefineById(
			final long productDefineId) throws Exception {
		ProductDefine productDefine = productDefineDao.findById(productDefineId);
		return productDefine != null ? new ProductDefineBean(productDefine) : null;
	}

	/**
	 * 取得产品词汇�?
	 * 
	 * @param productId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductGlossaryBean[] doGetProductGlossaries(
			final long productVersionId) throws Exception {
		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		ProductVersionRelateDAOQueryBean subQueryBean = new ProductVersionRelateDAOQueryBean();

		subQueryBean.addProductElementIdSelectProperty();

		subQueryBean.createCriteria().andProductDefineIdEqualTo(productVersion.getProductDefineId())
				.andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName());

		ProductGlossaryDAOQueryBean queryBean = new ProductGlossaryDAOQueryBean();

		queryBean.createCriteria().andProductIdEqualTo(productVersion.getProductDefineId()).andIdIn(subQueryBean,
				this.productVersionRelateDao);

		return ProductGlossaryBean.toArray(productGlossaryDao.query(queryBean));
	}

	/**
	 * 根据ID取得产品词汇
	 * 
	 * @param productGlossaryId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductGlossaryBean doGetProductGlossaryById(
			final long productGlossaryId) throws Exception {
		ProductGlossary productGlossary = productGlossaryDao.findById(productGlossaryId);

		return productGlossary != null ? new ProductGlossaryBean(productGlossary) : null;
	}

	/**
	 * 添加产品词汇
	 * 
	 * @param productId
	 * 
	 * @param productGlossary
	 * @throws Exception
	 */
	protected void doAddProductGlossary(final long productVersionId,
			final com.ourteam.product.requirement.domain.ProductGlossaryBean productGlossary) throws Exception {

		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		if (productVersion != null) {
			productGlossary.setProductId(productVersion.getProductDefineId());
			productGlossary.setSinceVersionId(productVersion.getId());
		}

		String code = getProductElementCode(productGlossary.getProductId(), ProductElementTypeEnum.PRODUCT_GLOSSARY);

		productGlossary.setCode(code);

		productGlossaryDao.insert(productGlossary.convertToProductGlossary());

		if (productVersion != null) {

			ProductVersionRelate versionRelate = new ProductVersionRelate();

			versionRelate.setProductDefineId(productVersion.getProductDefineId());

			versionRelate.setProductElementId(productGlossary.getId());

			versionRelate.setProductVersionId(productVersionId);

			versionRelate.setProductElementType(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName());

			this.productVersionRelateDao.insert(versionRelate);
		}

		ProductGlossaryChangLog changLog = new ProductGlossaryChangLog();

		changLog.setBeforChangeContent("");

		changLog.setAfterChangeContent(productGlossary.getContent());

		changLog.setProductGlossaryId(productGlossary.getId());

		changLog.setEditDate(productGlossary.getLastEditDate());

		changLog.setEditorId(productGlossary.getCreatorId());

		productGlossaryChangLogDao.insert(changLog);

	}

	/**
	 * 更新产品词汇
	 * 
	 * @param productGlossary
	 * @throws Exception
	 */
	protected void doModifyProductGlossary(
			final com.ourteam.product.requirement.domain.ProductGlossaryBean productGlossary) throws Exception {

		ProductGlossary oldProductGlossary = productGlossaryDao.findById(productGlossary.getId());

		productGlossaryDao.update(productGlossary.convertToProductGlossary());

		if ((oldProductGlossary.getContent() == null && productGlossary.getContent() == null)
				|| (oldProductGlossary.getContent() != null
						&& oldProductGlossary.getContent().equals(productGlossary.getContent()))
				|| (productGlossary.getContent() != null
						&& productGlossary.getContent().equals(oldProductGlossary.getContent()))) {
			return;

		} else {
			ProductGlossaryChangLog changLog = new ProductGlossaryChangLog();

			changLog.setBeforChangeContent(oldProductGlossary.getContent());

			changLog.setAfterChangeContent(productGlossary.getContent());

			changLog.setProductGlossaryId(productGlossary.getId());

			changLog.setEditDate(productGlossary.getLastEditDate());

			changLog.setEditorId(productGlossary.getLastEditorId());

			productGlossaryChangLogDao.insert(changLog);
		}

	}

	/**
	 * 删除产品词汇
	 * 
	 * @param productGlossaryIds
	 * @throws Exception
	 */
	protected void doDeleteProductGlossaries(final long[] productGlossaryIds) throws Exception {

		ProductGlossaryDAOQueryBean queryBean = new ProductGlossaryDAOQueryBean();

		queryBean.createCriteria().andIdIn(productGlossaryIds);

		productGlossaryDao.delete(queryBean);

		ProductVersionRelateDAOQueryBean relateDAOQueryBean = new ProductVersionRelateDAOQueryBean();

		relateDAOQueryBean.createCriteria()
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName())
				.andProductElementIdIn(productGlossaryIds);

		this.productVersionRelateDao.delete(relateDAOQueryBean);
	}

	/**
	 * 查询产品�?�?
	 * 
	 * @param qeryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementBean[] doQueryProductRequirements(
			final com.ourteam.product.requirement.dao.ProductRequirementDAOQueryBean queryBean) throws Exception {

		return ProductRequirementBean.toArray(this.productRequirementDao.query(queryBean));
	}

	/**
	 * 查询产品�?求数�?
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductRequirementCount(
			final com.ourteam.product.requirement.dao.ProductRequirementDAOQueryBean queryBean) throws Exception {
		return this.productRequirementDao.queryCount(queryBean);
	}

	/**
	 * 根据父ID取得产品�?�?
	 * 
	 * @param productDefineId
	 * 
	 * @param parentRequiremntId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementBean[] doGetProductRequirementByParentId(
			final long productVersionId, final long parentRequiremntId) throws Exception {

		ProductVersionRelateDAOQueryBean subQueryBean = new ProductVersionRelateDAOQueryBean();

		subQueryBean.addProductElementIdSelectProperty();

		subQueryBean.createCriteria().andProductDefineIdEqualToForeignKey(IProductRequirementDAO.ProductDefineId)
				.andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

		ProductRequirementDAOQueryBean queryBean = new ProductRequirementDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(parentRequiremntId).andIdIn(subQueryBean,
				productVersionRelateDao);

		queryBean.setSortProperty(IProductRequirementDAO.SortIndex);

		return ProductRequirementBean.toArray(this.productRequirementDao.query(queryBean));

	}

	/**
	 * 根据ID取得产品�?�?
	 * 
	 * @param productRequirementId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementBean doGetProductRequirementById(
			final long productRequirementId) throws Exception {
		ProductRequirement productRequirement = this.productRequirementDao.findById(productRequirementId);

		return new ProductRequirementBean(productRequirement);
	}

	/**
	 * 新建产品�?�?
	 * 
	 * @param productVersionId
	 * 
	 * @param productRequirement
	 * @throws Exception
	 */
	protected void doAddNewProductRequirement(final long productVersionId,
			final com.ourteam.product.requirement.domain.ProductRequirementBean productRequirement) throws Exception {

		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		productRequirement.setProductDefineId(productVersion.getProductDefineId());

		String requestCode = getProductElementCode(productVersion.getProductDefineId(),
				ProductElementTypeEnum.PRODUCT_REQUIREMENT);

		productRequirement.setRequestCode(requestCode);

		productRequirement.setCreateDate(new Date());

		ProductRequirementDAOQueryBean queryBean = new ProductRequirementDAOQueryBean();

		queryBean.setSortProperty(IProductRequirementDAO.SortIndex);

		ProductRequirementDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productVersion.getProductDefineId())
				.andParentIdEqualTo(productRequirement.getParentId());

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

		criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

		ProductRequirement[] requirements = this.productRequirementDao.query(queryBean);

		for (int i = 0; i < requirements.length; i++) {
			if (requirements[i].getSortIndex() != (i + 1)) {
				requirements[i].setSortIndex(i + 1);
				this.productRequirementDao.update(requirements[i]);
			}
		}

		productRequirement.setSortIndex(requirements.length + 1);

		this.productRequirementDao.insert(productRequirement.convertToProductRequirement());

		ProductVersionRelate versionRelate = new ProductVersionRelate();

		versionRelate.setProductDefineId(productRequirement.getProductDefineId());

		versionRelate.setProductElementId(productRequirement.getId());

		versionRelate.setProductVersionId(productVersionId);

		versionRelate.setProductElementType(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

		this.productVersionRelateDao.insert(versionRelate);
	}

	/**
	 * 修改产品�?�?
	 * 
	 * @param productRequirement
	 * @throws Exception
	 */
	protected void doModifyProductRequirement(
			final com.ourteam.product.requirement.domain.ProductRequirementBean productRequirement) throws Exception {

		productRequirement.setLastEditDate(new Date());

		this.productRequirementDao.update(productRequirement.convertToProductRequirement());
	}

	protected void doSetProductRequirementSort(final long productVersionId, final long productRequirementId,
			final int sortIndex, final long submitorId) throws Exception {

		ProductRequirement productRequirement = this.productRequirementDao.findById(productRequirementId);

		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		ProductRequirementDAOQueryBean queryBean = new ProductRequirementDAOQueryBean();

		queryBean.setSortProperty(IProductRequirementDAO.SortIndex);

		ProductRequirementDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productVersion.getProductDefineId())
				.andParentIdEqualTo(productRequirement.getParentId());

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

		criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

		ProductRequirement[] requirements = this.productRequirementDao.query(queryBean);

		if (requirements.length >= sortIndex && sortIndex > 0) {

			requirements[sortIndex - 1].setSortIndex(productRequirement.getSortIndex());
			requirements[sortIndex - 1].setLastEditDate(new Date());
			requirements[sortIndex - 1].setLastEditorId(submitorId);

			productRequirement.setSortIndex(sortIndex);
			productRequirement.setLastEditDate(new Date());
			productRequirement.setLastEditorId(submitorId);

			this.productRequirementDao
					.batchUpdate(new ProductRequirement[] { productRequirement, requirements[sortIndex - 1] });
		}

	}

	/**
	 * 删除产品�?�?
	 * 
	 * @param productRequirementIds
	 * @throws Exception
	 */
	protected void doDeleteProductRequirements(final long[] productRequirementIds) throws Exception {

		if (ArrayUtils.isEmpty(productRequirementIds)) {
			return;
		}

		ProductVersionRelateDAOQueryBean relateDAOQueryBean = new ProductVersionRelateDAOQueryBean();

		relateDAOQueryBean.createCriteria()
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName())
				.andProductElementIdIn(productRequirementIds);

		ProductVersionRelate[] versionRelates = this.productVersionRelateDao.query(relateDAOQueryBean);

		for (int i = 0; i < versionRelates.length; i++) {

			ProductRequirement requirement = this.productRequirementDao
					.findById(versionRelates[i].getProductElementId());

			if (requirement == null) {
				continue;
			}

			this.productRequirementDao.delete(requirement);

			ProductRequirementDAOQueryBean queryBean = new ProductRequirementDAOQueryBean();

			queryBean.setSortProperty(IProductRequirementDAO.SortIndex);

			ProductRequirementDAOQueryBean.Criteria criteria = queryBean.createCriteria();

			criteria.andProductDefineIdEqualTo(requirement.getProductDefineId())
					.andParentIdEqualTo(requirement.getParentId());

			ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

			versionRelateQueryBean.addProductElementIdSelectProperty();

			versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(versionRelates[i].getProductVersionId())
					.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

			criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

			ProductRequirement[] requirements = this.productRequirementDao.query(queryBean);

			for (int j = 0; j < requirements.length; j++) {
				requirements[j].setSortIndex(j + 1);
			}

			this.productRequirementDao.batchUpdate(requirements);

		}

		this.productVersionRelateDao.delete(relateDAOQueryBean);

	}

	/**
	 * 查询产品词汇�?
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductGlossaryBean[] doQueryProductGlossary(
			final com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean queryBean) throws Exception {

		return ProductGlossaryBean.toArray(this.productGlossaryDao.query(queryBean));
	}

	/**
	 * 查询产品词汇表数�?
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductGlossaryCount(
			final com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean queryBean) throws Exception {

		return this.productGlossaryDao.queryCount(queryBean);
	}

	/**
	 * 根据版本查询产品词汇术语
	 * 
	 * @param productVersion
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductGlossaryBean[] doQueryProductGlossaryByVersion(
			final long productVersionId,
			final com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean queryBean) throws Exception {

		ProductGlossaryDAOQueryBean daoQueryBean = queryBean;

		if (daoQueryBean == null) {
			daoQueryBean = new ProductGlossaryDAOQueryBean();
		}

		ProductVersionRelateDAOQueryBean subQueryBean = new ProductVersionRelateDAOQueryBean();

		subQueryBean.addProductElementIdSelectProperty();

		subQueryBean.createCriteria().andProductDefineIdEqualToForeignKey(IProductGlossaryDAO.ProductId)
				.andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName());

		if (daoQueryBean.getOredCriteria().isEmpty()) {
			daoQueryBean.createCriteria().andIdIn(subQueryBean, this.productVersionRelateDao);
		} else {
			List<ProductGlossaryDAOQueryBean.Criteria> criterias = daoQueryBean.getOredCriteria();

			for (Iterator<ProductGlossaryDAOQueryBean.Criteria> iterator = criterias.iterator(); iterator.hasNext();) {
				iterator.next().andIdIn(subQueryBean, this.productVersionRelateDao);

			}
		}

		return queryProductGlossary(daoQueryBean);
	}

	/**
	 * 根据版本查询产品词汇术语数量
	 * 
	 * @param productVersion
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductGlossaryCountByVersion(final long productVersionId,
			final com.ourteam.product.requirement.dao.ProductGlossaryDAOQueryBean queryBean) throws Exception {

		ProductGlossaryDAOQueryBean daoQueryBean = queryBean;

		if (daoQueryBean == null) {
			daoQueryBean = new ProductGlossaryDAOQueryBean();
		}

		ProductVersionRelateDAOQueryBean subQueryBean = new ProductVersionRelateDAOQueryBean();

		subQueryBean.addProductElementIdSelectProperty();

		subQueryBean.createCriteria().andProductDefineIdEqualToForeignKey(IProductGlossaryDAO.ProductId)
				.andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_GLOSSARY.getName());

		if (daoQueryBean.getOredCriteria().isEmpty()) {
			daoQueryBean.createCriteria().andIdIn(subQueryBean, this.productVersionRelateDao);
		} else {
			List<ProductGlossaryDAOQueryBean.Criteria> criterias = daoQueryBean.getOredCriteria();

			for (Iterator<ProductGlossaryDAOQueryBean.Criteria> iterator = criterias.iterator(); iterator.hasNext();) {
				iterator.next().andIdIn(subQueryBean, this.productVersionRelateDao);

			}
		}

		return queryProductGlossaryCount(daoQueryBean);
	}

	/**
	 * 取得产品特�??
	 * 
	 * @param productVersionId
	 * 
	 * @param parentId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductFeatureBean[] doGetProductFeatureByParentId(
			final long productVersionId, final long parentId) throws Exception {

		ProductVersionRelateDAOQueryBean subQueryBean = new ProductVersionRelateDAOQueryBean();

		subQueryBean.addProductElementIdSelectProperty();

		subQueryBean.createCriteria().andProductDefineIdEqualToForeignKey(IProductFeatureDAO.ProductDefineId)
				.andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

		ProductFeatureDAOQueryBean queryBean = new ProductFeatureDAOQueryBean();

		queryBean.createCriteria().andParentIdEqualTo(parentId).andIdIn(subQueryBean, productVersionRelateDao);

		queryBean.setSortProperty(IProductFeatureDAO.SortIndex);

		return ProductFeatureBean.toArray(this.productFeatureDao.query(queryBean));
	}

	/**
	 *
	 * 
	 * @param productVersionId
	 * 
	 * @param productFeatureBean
	 * @throws Exception
	 */
	protected void doAddNewProductFeature(final long productVersionId,
			final com.ourteam.product.requirement.domain.ProductFeatureBean productFeatureBean) throws Exception {

		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		productFeatureBean.setProductDefineId(productVersion.getProductDefineId());

		String featureCode = getProductElementCode(productVersion.getProductDefineId(),
				ProductElementTypeEnum.PRODUCT_FEATURE);

		productFeatureBean.setFeatureCode(featureCode);

		ProductFeatureDAOQueryBean queryBean = new ProductFeatureDAOQueryBean();

		queryBean.setSortProperty(IProductFeatureDAO.SortIndex);

		ProductFeatureDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productVersion.getProductDefineId())
				.andParentIdEqualTo(productFeatureBean.getParentId());

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

		criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

		ProductFeature[] features = this.productFeatureDao.query(queryBean);

		for (int i = 0; i < features.length; i++) {
			if (features[i].getSortIndex() != (i + 1)) {
				features[i].setSortIndex(i + 1);
				this.productFeatureDao.update(features[i]);
			}
		}

		productFeatureBean.setSortIndex(features.length + 1);

		this.productFeatureDao.insert(productFeatureBean.convertToProductFeature());

		ProductVersionRelate versionRelate = new ProductVersionRelate();

		versionRelate.setProductDefineId(productVersion.getProductDefineId());

		versionRelate.setProductElementId(productFeatureBean.getId());

		versionRelate.setProductVersionId(productVersionId);

		versionRelate.setProductElementType(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

		this.productVersionRelateDao.insert(versionRelate);
	}

	/**
	 *
	 * 
	 * @param productFeatureBean
	 * @throws Exception
	 */
	protected void doModifyProductFeature(
			final com.ourteam.product.requirement.domain.ProductFeatureBean productFeatureBean) throws Exception {

		this.productFeatureDao.update(productFeatureBean.convertToProductFeature());
	}

	protected void doSetProductFeatureSort(final long productVersionId, final long productFeatureId,
			final int sortIndex, final long submitorId) throws Exception {

		ProductFeature productFeature = this.productFeatureDao.findById(productFeatureId);

		ProductVersion productVersion = this.productVersionDao.findById(productVersionId);

		ProductFeatureDAOQueryBean queryBean = new ProductFeatureDAOQueryBean();

		queryBean.setSortProperty(IProductFeatureDAO.SortIndex);

		ProductFeatureDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productVersion.getProductDefineId())
				.andParentIdEqualTo(productFeature.getParentId());

		ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

		versionRelateQueryBean.addProductElementIdSelectProperty();

		versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

		criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

		ProductFeature[] features = this.productFeatureDao.query(queryBean);

		if (features.length >= sortIndex && sortIndex > 0) {

			features[sortIndex - 1].setSortIndex(productFeature.getSortIndex());
			// features[sortIndex - 1].setLastEditDate(new Date());
			// features[sortIndex - 1].setLastEditorId(submitorId);

			productFeature.setSortIndex(sortIndex);
			// productFeature.setLastEditDate(new Date());
			// productFeature.setLastEditorId(submitorId);

			this.productFeatureDao.batchUpdate(new ProductFeature[] { productFeature, features[sortIndex - 1] });
		}

	}

	/**
	 *
	 * 
	 * @param productFeatureIds
	 * @throws Exception
	 */
	protected void doDeleteProductFeatures(final long[] productFeatureIds) throws Exception {

		if (ArrayUtils.isEmpty(productFeatureIds)) {
			return;
		}

		ProductVersionRelateDAOQueryBean relateDAOQueryBean = new ProductVersionRelateDAOQueryBean();

		relateDAOQueryBean.createCriteria()
				.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName())
				.andProductElementIdIn(productFeatureIds);

		ProductVersionRelate[] versionRelates = this.productVersionRelateDao.query(relateDAOQueryBean);

		for (int i = 0; i < versionRelates.length; i++) {

			ProductFeature feature = this.productFeatureDao.findById(versionRelates[i].getProductElementId());

			if (feature == null) {
				continue;
			}

			this.productFeatureDao.delete(feature);

			ProductFeatureDAOQueryBean queryBean = new ProductFeatureDAOQueryBean();

			queryBean.setSortProperty(IProductFeatureDAO.SortIndex);

			ProductFeatureDAOQueryBean.Criteria criteria = queryBean.createCriteria();

			criteria.andProductDefineIdEqualTo(feature.getProductDefineId()).andParentIdEqualTo(feature.getParentId());

			ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

			versionRelateQueryBean.addProductElementIdSelectProperty();

			versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(versionRelates[i].getProductVersionId())
					.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

			criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());

			ProductFeature[] features = this.productFeatureDao.query(queryBean);

			for (int j = 0; j < features.length; j++) {
				features[j].setSortIndex(j + 1);
			}

			this.productFeatureDao.batchUpdate(features);

		}

		this.productVersionRelateDao.delete(relateDAOQueryBean);

	}

	/**
	 * 根据ID取得产品特�??
	 * 
	 * @param productFeatureId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductFeatureBean doGetProductFeatureById(
			final long productFeatureId) throws Exception {

		ProductFeature productFeature = this.productFeatureDao.findById(productFeatureId);

		return productFeature != null ? new ProductFeatureBean(productFeature) : null;
	}

	/**
	 * 查询产品角色定义
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRoleDefineBean[] doQueryProductRoleDefines(
			final com.ourteam.product.requirement.dao.ProductRoleDefineDAOQueryBean queryBean) throws Exception {
		return ProductRoleDefineBean.toArray(this.productRoleDefineDao.query(queryBean));
	}

	/**
	 * 查询产品角色定义数量
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductRoleDefineCount(
			final com.ourteam.product.requirement.dao.ProductRoleDefineDAOQueryBean queryBean) throws Exception {
		return this.productRoleDefineDao.queryCount(queryBean);
	}

	/**
	 * 新增产品角色定义
	 * 
	 * @param productRoleDefine
	 * @throws Exception
	 */
	protected void doAddNewProductRoleDefine(
			final com.ourteam.product.requirement.domain.ProductRoleDefineBean productRoleDefine) throws Exception {
		this.productRoleDefineDao.insert(productRoleDefine.convertToProductRoleDefine());
	}

	/**
	 * 修改产品角色定义
	 * 
	 * @param productRoleDefine
	 * @throws Exception
	 */
	protected void doModifyProductRoleDefine(
			final com.ourteam.product.requirement.domain.ProductRoleDefineBean productRoleDefineBean) throws Exception {
		this.productRoleDefineDao.update(productRoleDefineBean.convertToProductRoleDefine());
	}

	/**
	 * 删除产品角色定义
	 * 
	 * @param productRoleDefineIds
	 * @throws Exception
	 */
	protected void doDeleteProductRoleDefines(final long[] productRoleDefineIds) throws Exception {

		ProductRoleDefineDAOQueryBean queryBean = new ProductRoleDefineDAOQueryBean();

		queryBean.createCriteria().andIdIn(productRoleDefineIds);

		this.productRoleDefineDao.delete(queryBean);
	}

	/**
	 * 根据ID取得产品角色定义
	 * 
	 * @param productRoleDefineId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRoleDefineBean doGetProductRoleDefineById(
			final long productRoleDefineId) throws Exception {

		ProductRoleDefine productRoleDefine = this.productRoleDefineDao.findById(productRoleDefineId);

		return productRoleDefine != null ? new ProductRoleDefineBean(productRoleDefine) : null;
	}

	/**
	 * 新建产品团队成员
	 * 
	 * @param productTeamBean
	 * @throws Exception
	 */
	protected void doAddNewProductTeamStaffer(
			final com.ourteam.product.requirement.domain.ProductTeamBean productTeamBean) throws Exception {

		this.productTeamDao.insert(productTeamBean.convertTo());

	}

	/**
	 *
	 * 
	 * @param productTeamBean
	 * @throws Exception
	 */
	protected void doModifyProductTeamStaffer(
			final com.ourteam.product.requirement.domain.ProductTeamBean productTeamBean) throws Exception {
		this.productTeamDao.update(productTeamBean.convertTo());
	}

	/**
	 *
	 * 
	 * @param productTeamId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductTeamBean doGetProductTeamStafferById(
			final long productTeamId) throws Exception {

		ProductTeam productTeam = this.productTeamDao.findById(productTeamId);

		return productTeam != null ? new ProductTeamBean(productTeam) : null;
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductTeamBean[] doQueryProductTeamStaffers(
			final com.ourteam.product.requirement.dao.ProductTeamDAOQueryBean queryBean) throws Exception {

		return ProductTeamBean.toArray(this.productTeamDao.query(queryBean));

	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductTeamStafferCount(
			final com.ourteam.product.requirement.dao.ProductTeamDAOQueryBean queryBean) throws Exception {

		return this.productTeamDao.queryCount(queryBean);

	}

	/**
	 *
	 * 
	 * @param productTeamIds
	 * @throws Exception
	 */
	protected void doDeleteProductTeamStaffers(final long[] productTeamIds) throws Exception {

		if (ArrayUtils.isNotEmpty(productTeamIds)) {

			ProductTeamDAOQueryBean queryBean = new ProductTeamDAOQueryBean();

			queryBean.createCriteria().andIdIn(productTeamIds);

			this.productTeamDao.delete(queryBean);

		}

	}

	/**
	 *
	 * 
	 * @param productRequirementFeatureRelates
	 * @throws Exception
	 */
	protected void doAddProductRequirementFeatureRelate(
			final com.ourteam.product.requirement.domain.ProductRequirementFeatureRelateBean[] productRequirementFeatureRelates)
			throws Exception {
		ProductRequirementFeatureRelate[] relates = new ProductRequirementFeatureRelate[productRequirementFeatureRelates.length];

		for (int i = 0; i < relates.length; i++) {
			relates[i] = productRequirementFeatureRelates[i].convertToProductRequirementFeatureRelate();

		}

		this.productRequirementFeatureRelateDao.batchInsert(relates);
	}

	/**
	 * 删除产品�?求与特征关联
	 * 
	 * @param productRequirementFeatureRelateIds
	 * @throws Exception
	 */
	protected void doRemoveProductRequirementFeatureRelates(final long[] productRequirementFeatureRelateIds)
			throws Exception {
		ProductRequirementFeatureRelateDAOQueryBean queryBean = new ProductRequirementFeatureRelateDAOQueryBean();

		queryBean.createCriteria().andIdIn(productRequirementFeatureRelateIds);

		this.productRequirementFeatureRelateDao.delete(queryBean);
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementFeatureRelateBean[] doQueryProductRequirementFeatureRelates(
			final com.ourteam.product.requirement.dao.ProductRequirementFeatureRelateDAOQueryBean queryBean)
			throws Exception {
		return ProductRequirementFeatureRelateBean.toArray(this.productRequirementFeatureRelateDao.query(queryBean));
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductRequirementFeatureRelateCount(
			final com.ourteam.product.requirement.dao.ProductRequirementFeatureRelateDAOQueryBean queryBean)
			throws Exception {
		return this.productRequirementFeatureRelateDao.queryCount(queryBean);
	}

	/**
	 *
	 * 
	 * @param productRequirementFeatureRelateBean
	 * @throws Exception
	 */
	protected void doModifyProductRequirementFeatureRelate(
			final com.ourteam.product.requirement.domain.ProductRequirementFeatureRelateBean productRequirementFeatureRelateBean)
			throws Exception {

		this.productRequirementFeatureRelateDao
				.update(productRequirementFeatureRelateBean.convertToProductRequirementFeatureRelate());
	}

	/**
	 *
	 * 
	 * @param productRequirementRelateBeans
	 * @throws Exception
	 */
	protected void doAddProductRequirementRelates(
			final com.ourteam.product.requirement.domain.ProductRequirementRelateBean[] requirementRelates)
			throws Exception {

		ProductRequirementRelate[] relates = new ProductRequirementRelate[requirementRelates.length];

		for (int i = 0; i < relates.length; i++) {
			relates[i] = requirementRelates[i].convertToProductRequirementRelate();

		}

		this.productRequirementRelateDao.batchInsert(relates);
	}

	/**
	 *
	 * 
	 * @param productRequirementId
	 * 
	 * @param relateTypeEnum
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementRelateBean[] doGetProductRequirementRelate(
			final long productRequirementId,
			final com.ourteam.product.requirement.domain.ProductRequirementRelateTypeEnum relateTypeEnum)
			throws Exception {

		ProductRequirementRelateDAOQueryBean queryBean = new ProductRequirementRelateDAOQueryBean();

		queryBean.createCriteria().andRequirementIdEqualTo(productRequirementId)
				.andRelatedTypeEqualTo(relateTypeEnum.getName());

		return queryProductRequirementRelates(queryBean);
	}

	/**
	 *
	 * 
	 * @param relateIds
	 * @throws Exception
	 */
	protected void doRemoveProductRequirementRelates(final long[] relateIds) throws Exception {

		ProductRequirementRelateDAOQueryBean queryBean = new ProductRequirementRelateDAOQueryBean();

		queryBean.createCriteria().andIdIn(relateIds);

		this.productRequirementRelateDao.delete(queryBean);
	}

	/**
	 * 查询�?求关�?
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductRequirementRelateBean[] doQueryProductRequirementRelates(
			final com.ourteam.product.requirement.dao.ProductRequirementRelateDAOQueryBean queryBean) throws Exception {

		return ProductRequirementRelateBean.toArray(this.productRequirementRelateDao.query(queryBean));
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductRequirementRelateCount(
			final com.ourteam.product.requirement.dao.ProductRequirementRelateDAOQueryBean queryBean) throws Exception {

		return this.productRequirementRelateDao.queryCount(queryBean);
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductVersionRelateBean[] doQueryProductVersionRelates(
			final com.ourteam.product.requirement.dao.ProductVersionRelateDAOQueryBean queryBean) throws Exception {
		return ProductVersionRelateBean.toArray(this.productVersionRelateDao.query(queryBean));
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductVersionRelateCount(
			final com.ourteam.product.requirement.dao.ProductVersionRelateDAOQueryBean queryBean) throws Exception {
		return this.productVersionRelateDao.queryCount(queryBean);
	}

	/**
	 *
	 * 
	 * @param aProductFeatureCheckList
	 * @throws Exception
	 */
	protected void doAddNewProductFeatureCheckList(
			final com.ourteam.product.requirement.domain.ProductFeatureCheckListBean aProductFeatureCheckList)
			throws Exception {

		ProductFeatureCheckListDAOQueryBean queryBean = new ProductFeatureCheckListDAOQueryBean();

		queryBean.createCriteria().andProductFeatureIdEqualTo(aProductFeatureCheckList.getProductFeatureId());

		int count = this.productFeatureCheckListDao.queryCount(queryBean);

		aProductFeatureCheckList.setSortIndex(count + 1);

		this.productFeatureCheckListDao.insert(aProductFeatureCheckList.convertToProductFeatureCheckList());
	}

	/**
	 *
	 * 
	 * @param aProductFeatureCheckList
	 * @throws Exception
	 */
	protected void doMoodifyProductFeatureCheckList(
			final com.ourteam.product.requirement.domain.ProductFeatureCheckListBean aProductFeatureCheckList)
			throws Exception {

		this.productFeatureCheckListDao.update(aProductFeatureCheckList.convertToProductFeatureCheckList());
	}

	/**
	 *
	 * 
	 * @param ids
	 * @throws Exception
	 */
	protected void doDeleteProductFeatureCheckList(final long[] ids) throws Exception {

		if (ArrayUtils.isEmpty(ids)) {
			return;
		}

		ProductFeatureCheckList checkList = this.productFeatureCheckListDao.findById(ids[0]);

		ProductFeatureCheckListDAOQueryBean queryBean = new ProductFeatureCheckListDAOQueryBean();

		queryBean.createCriteria().andIdIn(ids);

		this.productFeatureCheckListDao.delete(queryBean);

		queryBean.clear();

		queryBean.setSortProperty(IProductFeatureCheckListDAO.SortIndex);

		queryBean.createCriteria().andProductFeatureIdEqualTo(checkList.getProductFeatureId());

		ProductFeatureCheckList[] checkLists = this.productFeatureCheckListDao.query(queryBean);

		for (int i = 0; i < checkLists.length; i++) {
			checkLists[i].setSortIndex(i + 1);
		}

		this.productFeatureCheckListDao.batchUpdate(checkLists);

	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductFeatureCheckListBean[] doQueryProductFeatureCheckList(
			final com.ourteam.product.requirement.dao.ProductFeatureCheckListDAOQueryBean queryBean) throws Exception {

		return ProductFeatureCheckListBean.toArray(this.productFeatureCheckListDao.query(queryBean));
	}

	/**
	 *
	 * 
	 * @param queryBean
	 * @throws Exception
	 */
	protected int doQueryProductFeatureCheckListCount(
			final com.ourteam.product.requirement.dao.ProductFeatureCheckListDAOQueryBean queryBean) throws Exception {

		if (queryBean.getSortProperties().isEmpty()) {
			queryBean.setSortProperty(IProductFeatureCheckListDAO.SortIndex);
		}

		return this.productFeatureCheckListDao.queryCount(queryBean);
	}

	/**
	 *
	 * 
	 * @param aProductFeatureCheckListId
	 * @throws Exception
	 */
	protected com.ourteam.product.requirement.domain.ProductFeatureCheckListBean doGetProductFeatureCheckListById(
			final long aProductFeatureCheckListId) throws Exception {

		ProductFeatureCheckList checkList = this.productFeatureCheckListDao.findById(aProductFeatureCheckListId);

		return checkList != null ? new ProductFeatureCheckListBean(checkList) : null;
	}

	protected String getProductElementCode(long productDefineId, ProductElementTypeEnum typeEnum) throws Exception {

		String code = "";

		ProductCodeGenDAOQueryBean queryBean = new ProductCodeGenDAOQueryBean();

		queryBean.createCriteria().andCodeTypeEqualTo(typeEnum.getName()).andProductDefineIdEqualTo(productDefineId);

		ProductCodeGen[] codeGens = this.productCodeGenDao.query(queryBean);

		if (ArrayUtils.isEmpty(codeGens)) {

			ProductCodeGen codeGen = new ProductCodeGen();

			codeGen.setProductDefineId(productDefineId);

			codeGen.setCodeType(typeEnum.getName());

			codeGen.setSerialCode(1);

			ProductCodeTemplateDAOQueryBean templateDAOQueryBean = new ProductCodeTemplateDAOQueryBean();

			templateDAOQueryBean.createCriteria().andCodeTypeEqualTo(typeEnum.getName());

			ProductCodeTemplate[] templates = this.productCodeTemplateDao.query(templateDAOQueryBean);

			if (ArrayUtils.isNotEmpty(templates)) {

				code = StringUtils.replace(templates[0].getCodeFormateTemplate(), "${serial}",
						String.valueOf(codeGen.getSerialCode()));

			} else {
				throw new Exception(typeEnum.getName() + " Template Is Empty ");
			}

			this.productCodeGenDao.insert(codeGen);

		} else {
			ProductCodeGen codeGen = codeGens[0];

			codeGen.setSerialCode(codeGen.getSerialCode() + 1);

			this.productCodeGenDao.update(codeGen);

			code = StringUtils.replace(codeGen.getCodeFormateTemplate(), "${serial}",
					String.valueOf(codeGen.getSerialCode()));

		}

		return code;
	}

	@Override
	protected ProductFeatureBean[] doQueryProductFeatures(ProductFeatureDAOQueryBean queryBean) throws Exception {
		return ProductFeatureBean.toArray(this.productFeatureDao.query(queryBean));
	}

	@Override
	protected int doQueryProductFeatureCount(ProductFeatureDAOQueryBean queryBean) throws Exception {
		return this.productFeatureDao.queryCount(queryBean);
	}

	@Override
	protected void doAddNewProductRoleRelate(ProductRoleRelateBean aProductRoleRelate) throws Exception {
		this.productRoleRelateDao.insert(aProductRoleRelate.convertTo());
	}

	@Override
	protected void doModifyProductRoleRelate(ProductRoleRelateBean aProductRoleRelate) throws Exception {
		this.productRoleRelateDao.update(aProductRoleRelate.convertTo());
	}

	@Override
	protected void doDeleteProductRoleRelates(long[] aProductRoleRelateIds) throws Exception {

		if (ArrayUtils.isNotEmpty(aProductRoleRelateIds)) {
			ProductRoleRelateDAOQueryBean queryBean = new ProductRoleRelateDAOQueryBean();

			queryBean.createCriteria().andIdIn(aProductRoleRelateIds);

			this.productRoleRelateDao.delete(queryBean);

		}

	}

	@Override
	protected ProductRoleRelateBean doGetProductRoleRelateById(long aProductRoleRelateId) throws Exception {

		ProductRoleRelate roleRelate = this.productRoleRelateDao.findById(aProductRoleRelateId);

		return roleRelate != null ? new ProductRoleRelateBean(roleRelate) : null;
	}

	@Override
	protected ProductRoleRelateBean[] doQueryProductRoleRelates(ProductRoleRelateDAOQueryBean queryBean)
			throws Exception {
		return ProductRoleRelateBean.toArray(this.productRoleRelateDao.query(queryBean));
	}

	@Override
	protected int doQueryProductRoleRelateCount(ProductRoleRelateDAOQueryBean queryBean) throws Exception {
		return this.productRoleRelateDao.queryCount(queryBean);
	}

	@Override
	protected void doSetProductFeatureCheckListSort(long productFeatureId, long checkListItemId, int sortIndex,
			long submitorId) throws Exception {

		ProductFeatureCheckList productFeatureCheckList = this.productFeatureCheckListDao.findById(checkListItemId);

		ProductFeatureCheckListDAOQueryBean queryBean = new ProductFeatureCheckListDAOQueryBean();

		queryBean.setSortProperty(IProductFeatureCheckListDAO.SortIndex);

		ProductFeatureCheckListDAOQueryBean.Criteria criteria = queryBean.createCriteria();

		criteria.andProductFeatureIdEqualTo(productFeatureId);

		ProductFeatureCheckList[] checkLists = this.productFeatureCheckListDao.query(queryBean);

		if (checkLists.length >= sortIndex && sortIndex > 0) {

			checkLists[sortIndex - 1].setSortIndex(productFeatureCheckList.getSortIndex());

			productFeatureCheckList.setSortIndex(sortIndex);

			this.productFeatureCheckListDao
					.batchUpdate(new ProductFeatureCheckList[] { productFeatureCheckList, checkLists[sortIndex - 1] });
		}

	}

	@Override
	protected void doAddNewProductGlossaryRelate(ProductGlossaryRelateBean aProductGlossaryRelate) throws Exception {
		this.productGlossaryRelateDao.insert(aProductGlossaryRelate.convertTo());
	}

	@Override
	protected void doModifyProductGlossaryRelate(ProductGlossaryRelateBean aProductGlossaryRelate) throws Exception {
		this.productGlossaryRelateDao.update(aProductGlossaryRelate.convertTo());
	}

	@Override
	protected void doDeleteProductGlossaryRelates(long[] aProductGlossaryRelateIds) throws Exception {

		if (ArrayUtils.isEmpty(aProductGlossaryRelateIds)) {
			return;
		}

		ProductGlossaryRelateDAOQueryBean queryBean = new ProductGlossaryRelateDAOQueryBean();

		queryBean.createCriteria().andIdIn(aProductGlossaryRelateIds);

		this.productGlossaryRelateDao.delete(queryBean);

	}

	@Override
	protected ProductGlossaryRelateBean doGetProductGlossaryRelateById(long aProductGlossaryRelateId) throws Exception {

		ProductGlossaryRelate glossaryRelate = this.productGlossaryRelateDao.findById(aProductGlossaryRelateId);

		return glossaryRelate != null ? new ProductGlossaryRelateBean(glossaryRelate) : null;
	}

	@Override
	protected ProductGlossaryRelateBean[] doQueryProductGlossaryRelates(ProductGlossaryRelateDAOQueryBean queryBean)
			throws Exception {
		return ProductGlossaryRelateBean.toArray(this.productGlossaryRelateDao.query(queryBean));
	}

	@Override
	protected int doQueryProductGlossaryRelateCount(ProductGlossaryRelateDAOQueryBean queryBean) throws Exception {
		return this.productGlossaryRelateDao.queryCount(queryBean);
	}

	@Override
	protected void doAddNewProductGlossaryAttr(ProductGlossaryAttrBean aProductGlossaryAttr) throws Exception {
		this.productGlossaryAttrDao.insert(aProductGlossaryAttr.convertTo());
	}

	@Override
	protected void doModifyProductGlossaryAttr(ProductGlossaryAttrBean aProductGlossaryAttr) throws Exception {

		this.productGlossaryAttrDao.update(aProductGlossaryAttr.convertTo());

	}

	@Override
	protected void doDeleteProductGlossaryAttrs(long[] aProductGlossaryAttrIds) throws Exception {
		
		if (ArrayUtils.isEmpty(aProductGlossaryAttrIds)) {
			return;
		}

		ProductGlossaryAttrDAOQueryBean queryBean = new ProductGlossaryAttrDAOQueryBean();

		queryBean.createCriteria().andIdIn(aProductGlossaryAttrIds);

		this.productGlossaryAttrDao.delete(queryBean);

	}

	@Override
	protected ProductGlossaryAttrBean doGetProductGlossaryAttrById(long aProductGlossaryAttrId) throws Exception {

		ProductGlossaryAttr glossaryAttr = this.productGlossaryAttrDao.findById(aProductGlossaryAttrId);

		return glossaryAttr != null ? new ProductGlossaryAttrBean(glossaryAttr) : null;
	}

	@Override
	protected ProductGlossaryAttrBean[] doQueryProductGlossaryAttrs(ProductGlossaryAttrDAOQueryBean queryBean)
			throws Exception {

		return ProductGlossaryAttrBean.toArray(this.productGlossaryAttrDao.query(queryBean));
	}

	@Override
	protected int doQueryProductGlossaryAttrCount(ProductGlossaryAttrDAOQueryBean queryBean) throws Exception {
		return this.productGlossaryAttrDao.queryCount(queryBean);
	}

}
